package com.yuxue.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.yuxue.constant.Constant;
import com.yuxue.entity.PlateFileEntity;
import com.yuxue.enumtype.PlateColor;
import com.yuxue.service.PlateService;
import com.yuxue.util.FileUtil;
import com.yuxue.util.GenerateIdUtil;
import com.yuxue.util.ImageUtil;
import com.yuxue.util.PlateUtil;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.File;
import java.util.Map;
import java.util.Set;
import java.util.Vector;


@Service
public class PlateServiceImpl implements PlateService {

    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    @Override
    public Object recognise(String filePath, boolean reRecognise) {
        filePath = filePath.replaceAll("\\\\", "/");
        File f = new File(filePath);
        PlateFileEntity entity = new PlateFileEntity();
        entity.setTempPath(Constant.DEFAULT_TEMP_DIR);
        doRecognise(f, entity);
        // 查询debug文件
        if(!StringUtils.isEmpty(entity.getTempPath())) {
            Vector<String> debugFiles = new Vector<String>();
            FileUtil.getFiles(entity.getTempPath(), debugFiles);
            entity.setDebugFiles(debugFiles);
        }
        return entity;
    }


    /**
     * 单张图片 车牌识别
     * 拷贝文件到临时目录
     * 过程及结果更新数据库
     * @param f
     * @param e
     * @return
     */
    public Object doRecognise(File f, PlateFileEntity e) {
        if(!f.exists()) {
            return null;
        }

        String ct = GenerateIdUtil.getStrId();
        String targetPath = Constant.DEFAULT_TEMP_DIR + ct + (f.getName().substring(f.getName().lastIndexOf(".")));
        FileUtil.copyAndRename(f.getAbsolutePath(), targetPath); // 拷贝文件并且重命名

        // 创建临时目录， 存放过程图片
        String tempPath =  Constant.DEFAULT_TEMP_DIR + ct + "/";
        FileUtil.createDir(tempPath);
        e.setTempPath(tempPath);

        Boolean debug = false;
        Vector<Mat> dst = new Vector<>();

        Mat src = ImageUtil.imread(targetPath, CvType.CV_8UC3);
        final Mat resized = ImageUtil.narrow(src, 600, debug, tempPath); // 调整大小,加快后续步骤的计算效率
        Vector<Mat> blockMat = PlateUtil.findPlateByContours(src, resized, debug, tempPath);

        // 通过svm模型，找出可能是车牌的图块，存到dst中， 返回结果
        PlateUtil.hasPlate(blockMat, dst, debug, tempPath);

        Set<String> plates = Sets.newHashSet();
        dst.stream().forEach(inMat -> {
            PlateColor color = PlateUtil.getPlateColor(inMat, true, false, tempPath);
            String plate = PlateUtil.charsSegment(inMat, color, debug, tempPath);
            plates.add("<" + plate + "," + color.desc + ">");
        });
        e.setRecoPlate(plates.toString());

        new File(targetPath).delete();  // 删除拷贝的临时文件
        return 1;
    }

    @Override
    public Object getImgInfo(String imgPath) {
        Map<String, Object> result = Maps.newHashMap();
        String ct = GenerateIdUtil.getStrId();
        File f = new File(imgPath);
        if(f.exists()) {
            String targetPath = Constant.DEFAULT_TEMP_DIR + ct + (f.getName().substring(f.getName().lastIndexOf(".")));
            FileUtil.copyAndRename(f.getAbsolutePath(), targetPath);
            result.put("targetPath", targetPath);   // 返回临时路径给前端
            // 获取图片的基本信息
            Mat inMat = Imgcodecs.imread(targetPath);
            result.put("rows", inMat.rows());
            result.put("cols", inMat.cols());
        }
        return result;
    }


    @Override
    public Object getHSVValue(String imgPath, Integer row, Integer col) {
        Map<String, Object> result = Maps.newHashMap();
        Mat inMat = Imgcodecs.imread(imgPath);

        double[] rgb = inMat.get(row, col);
        result.put("RGB", JSONObject.toJSONString(rgb));

        Mat dst = new Mat(inMat.rows(), inMat.cols(), CvType.CV_32FC3);
        Imgproc.cvtColor(inMat, dst, Imgproc.COLOR_BGR2HSV); // 转到HSV空间进行处理

        double[] hsv = dst.get(row, col);
        result.put("HSV", (int)hsv[0] + ", " + (int)hsv[1] + ", " + (int)hsv[2]);
        return result;
    }


}
